<script>
import { debounce } from 'lodash'
import ImportExcel from '@/views/employee/components/importExcel.vue'
import MessageMuch from '@/views/employee/components/messageMuch.vue'
import Avatar from '@/components/Avatar/Avatar.vue'
import RoleList from '@/views/employee/components/RoleList.vue'
import { getDepartmentListAPI } from '@/api/departmentApi'
import { transitionToTreeData } from '@/utils'
import { getEmployeeListAPI, deleteEmployeeAPI } from '@/api/employeeApi'

export default {
  name: 'Employee',
  components: { Avatar, MessageMuch, ImportExcel, RoleList },
  data() {
    return {
      /* el-tree展示数据的结构 */
      defaultProps: {
        //需要显示的字段的名称
        name: 'name',
        // 读取子节点的字段名称
        children: 'children'
      },
      /* 部门列表(树形) */
      depts: [],
      /* 获取员工列表的参数 */
      queryParams: {
        // 当前页
        page: 1,
        // 一页多少条数据
        pagesize: 20,
        // 模糊查询
        keyword: undefined,
        // 部门id,根据部门ID查询当前部门及子部门的员工
        departmentId: ''
      },
      /* 员工列表数据的总条数 */
      total: 0,
      /* 员工列表 */
      employeeList: [],
      /* 是否显示上传Excel的弹框 */
      visibleExcel: false,
      /* 选中的员工列表 */
      selectEmployee: [],
      /* 是否显示群发消息的弹框 */
      showMessageMuch: false,
      /* 是否显示分配角色的弹框 */
      isShowRole: false
    }
  },
  methods: {
    /* 获取部门列表的请求函数 */
    async fetchDepartment() {
      try {
        // 调用getDepartmentListAPI()获取部门列表的接口(返回的是一个Promise对象)
        const { data } = await getDepartmentListAPI()
        // 保存转换后的树形部门列表数组(树形的结构)
        this.depts = transitionToTreeData(data)
        // 记录传智教育这个部门的ID
        this.queryParams.departmentId = this.depts[0].id
        // 选中节点(树的渲染是异步的)
        this.$nextTick(() => {
          // 此时意味着树渲染已经完毕了(选中当前的节点)
          // 1.通过key设置某个节点的当前选中状态使用此方法必须设置node-key属性	(key)待被选节点的key，若为null则取消当前高亮的节点
          this.$refs.tree.setCurrentKey(this.queryParams.departmentId)
          // 调用fetchEmployeeList()请求函数获取员工列表
          this.fetchEmployeeList()
        })
      } catch (e) {
        // 部门列表获取失败
        this.$message.error(e.message)
      }
    },
    /* 获取员工列表的请求函数 */
    async fetchEmployeeList() {
      try {
        // 调用getEmployeeListAPI(this.queryParams)接口函数传入当前的请求参数，该函数返回一个Promise对象
        const result = await getEmployeeListAPI(this.queryParams)
        // 提示用户获取成功
        this.$message.success(result.message)
        // 赋值total
        this.total = result.data.total
        // 赋值rows员工列表
        this.employeeList = result.data.rows
      } catch (e) {
        // 提示获取员工列表的失败
        this.$message.error(e.message)
      }
    },
    /* 点击删除员工按钮 删除员工列表的回调函数 */
    async handleEmployee(role) {
      const confirm = await this.$confirm(`此操作将永久删除${role.username}员工, 是否继续?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(e => e)
      if (confirm === 'cancel') return
      try {
        const { message } = await deleteEmployeeAPI(role.id)
        this.$message.success(message)
        if (this.employeeList.length <= 1) this.queryParams.page--
        this.fetchEmployeeList()
      } catch (e) {
        this.$message.error(e.message)
      }
    },
    /* tree节点被点击时的回调函数 */
    handleNodeClick(data, node, tree) {
      //共三个参数，依次为：传递给data属性的数组中该节点所对应的对象、节点对应的Node、节点组件本身
      // 记录当前的节点(部门)ID
      this.queryParams.departmentId = data.id
      // 清空搜索关键字
      // this.queryParams.keyword = undefined
      // 回到第一页
      this.queryParams.page = 1
      // 调用fetchEmployeeList()请求函数获取员工列表
      this.fetchEmployeeList()
    },
    /* 当前页展示的数据条数发生变化的回调函数 */
    handleSizeChange(size) {
      this.queryParams.pagesize = size
      this.fetchEmployeeList()
    },
    /* 当前页码发生变化的回调函数 */
    handleCurrentChange(page) {
      this.queryParams.page = page
      this.fetchEmployeeList()
    },
    /* 当表格选择项发生变化时会触发该事件(参数selection) */
    handleSelectionChange(selection) {
      this.selectEmployee = selection
    },
    /* 输入框的input回调函数(用于搜索员工) */
    handleInput: debounce(function() {
      // 回到第一页
      this.queryParams.page = 1
      // 调用fetchEmployeeList()请求函数获取员工列表
      this.fetchEmployeeList()
    }, 600),
    /* 点击导出excel按钮的回调函数 */
    async exportExcel() {
      // 提示用户是否要导出excel
      const confirm = await this.$confirm(`确定将员工列表导出为excel表格吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(e => e)
      // 如果点击了取消则return
      if (confirm === 'cancel') return
      // 默认拿到数组第一个对象的键(属性名)
      const header = Object.keys(this.employeeList[0])
      // 将员工列表转换为二维数组
      const data = this.employeeList.map(item => Object.values({ ...item, staffPhoto: '头像', formOfEmployment: item.formOfEmployment === 1 ? '正式' : '临时' }))
      const excel = await import('@/vendor/ExportExcel')
      excel.export_json_to_excel({
        header, // 表头（数组格式）
        data, // 数据（二维数组）[['陶品奇', 'web前端']]
        filename: '员工信息', // 导出的文件名称
        autoWidth: true, // 是否自适应宽度
        bookType: 'xlsx' // 文件后缀名
      })
    },
    /* 点击导入excel按钮的回调函数 */
    async importExcel() {
      // 显示弹框
      this.visibleExcel = true
    },
    /* ImportExcel组件批量导入员工成功的回调函数 */
    uploadSuccess() {
      // 调用fetchDepartment()重新获取部门列表
      this.fetchDepartment()
    },
    /* 点击群发按钮的回调函数 */
    handleSendMessage() {
      // 判断当前选中的员工数组列表是否为空，如果为空则提示用户reruen出去
      if (this.selectEmployee.length <= 0) return this.$message.warning('请选择要群发的员工')
      // 显示群发通知的组件
      this.showMessageMuch = true
    },
    /* MessageMuch子组件群发消息成功的自定义事件 */
    sendSuccess() {
      this.showMessageMuch = false
    },
    /* 点击分配角色的回调函数 */
    async handleDistributionRole(employee) {
      // 子组件显示的时候使用refs或子组件的实例调用子组件的方法获取角色列表以及获取当前员工已经拥有的角色列表
      // 先发送请求获取数据然后再显示弹层
      await this.$refs.role.fetchEnabledRole()
      await this.$refs.role.fetchEmployeeDetail(employee.id)
      this.isShowRole = true
    }
  },
  mounted() {
    // 调用fetchDepartment()请求函数获取部门列表
    this.fetchDepartment()
    /*调用fetchEmployeeList()请求函数获取员工列表
     this.fetchEmployeeList()*/
  }
}
</script>

<template>
  <div class="employee">
    <el-card class="layui-anim layui-anim-scale">
      <div class="container">
        <el-row>
          <el-col :span="4">
            <!--左边结构-->
            <div class="left">
              <!-- 搜索框(搜索对应的员工)-->
              <el-input placeholder="请输入员工姓名" prefix-icon="el-icon-search" v-model.trim="queryParams.keyword" @input="handleInput"></el-input>
              <!--树形组件(部门列表)-->
              <el-tree :data="depts" :props="defaultProps" :expand-on-click-node="false" default-expand-all highlight-current ref="tree" node-key="id" @node-click="handleNodeClick">
                <template #default="{data}"><span>{{ data.name }}</span></template>
              </el-tree>
            </div>
          </el-col>
          <el-col :span="20">
            <!--右边结构-->
            <div class="right">
              <!--工具栏-->
              <el-row>
                <el-col :span="4">
                  <el-button type="info" icon="el-icon-s-promotion" @click="handleSendMessage">群发通知</el-button>
                </el-col>
                <el-col :span="20">
                  <el-button type="primary" icon="el-icon-plus" @click="$router.push({name:'detail'})" v-per="'add-employee'">添加员工</el-button>
                  <el-button type="success" icon="el-icon-download" @click="importExcel">excel导入</el-button>
                  <el-button type="danger" icon="el-icon-upload2" @click="exportExcel">excel导出</el-button>
                </el-col>
              </el-row>
              <!--员工列表表格-->
              <el-table border stripe :data="employeeList" @selection-change="handleSelectionChange">
                <el-table-column type="selection" align="center"></el-table-column>
                <el-table-column label="员工ID" align="center">
                  <template #default="{row}">
                    <el-link type="danger" :underline="false">{{ row.id }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="头像" align="center">
                  <template #default="{row}">
                    <img :src="row.staffPhoto" v-if="row.staffPhoto"/>
                    <Avatar v-else :value="row.username"></Avatar>
                  </template>
                </el-table-column>
                <el-table-column label="姓名" align="center">
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.username }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="手机号" align="center" sortable>
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.mobile }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="工号" align="center" sortable>
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.workNumber }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="聘用形式" align="center">
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.formOfEmployment === 1 ? '正式' : '临时' }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="部门名称" align="center">
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.departmentName }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="入职时间" align="center" sortable>
                  <template #default="{row}">
                    <el-link type="primary" :underline="false">{{ row.timeOfEntry }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column label="操作" align="center" width="400">
                  <template #default="{row}">
                    <el-button type="primary" icon="el-icon-view" @click="$router.push({name:'detail',params:{id:row.id}})">查看员工</el-button>
                    <el-button type="success" icon="el-icon-edit" @click="handleDistributionRole(row)">分配角色</el-button>
                    <el-button type="danger" icon="el-icon-scissors" @click="handleEmployee(row)">删除员工</el-button>
                  </template>
                </el-table-column>
              </el-table>
              <!--分页器-->
              <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryParams.page" :page-sizes="[20, 30, 40, 50]" :page-size="queryParams.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total" background></el-pagination>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-card>
    <!--上传Excel的弹框-->
    <ImportExcel :visible-excel.sync="visibleExcel" @uploadSuccess="uploadSuccess"></ImportExcel>
    <!--群发通知的弹框-->
    <MessageMuch :showMessageMuch.sync="showMessageMuch" :selectEmployee="selectEmployee" @sendSuccess="sendSuccess"></MessageMuch>
    <!--分配角色的弹框-->
    <RoleList :isShowRole.sync="isShowRole" ref="role"></RoleList>
  </div>
</template>

<style scoped lang="scss">
.employee {
  .el-card {
    margin-top: 10px;

    ::v-deep .el-card__body {
      padding: unset;
    }

    .container {
      width: 100%;
    }

    .left {
      padding: 10px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);

      .el-tree {
        margin-top: 10px;
      }
    }

    .right {
      width: 100%;
      padding: 10px;

      .el-row {
        width: 100%;
        padding: 5px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);

        .el-col-20 {
          display: flex;
          justify-content: flex-end;
        }
      }

      .el-table {
        width: 100%;
        margin: 10px 0;
        box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);

        img {
          width: 50px;
          height: 50px;
          cursor: pointer;
          border-radius: 100%;
        }
      }

      .el-pagination {
        display: flex;
        justify-content: center;
        box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
        padding: 5px 0;
      }
    }
  }
}
</style>
